<template>
  <div class="relative w-full" ref="selectRef">
    <TreeSelect
      v-if="treeData"
      class="w-full"
      v-model:value="treeId"
      :tree-data="treeData"
      tree-default-expand-all
      :field-names="{
        label: 'structureName',
        value: 'id',
        children: 'children',
      }"
      size="small"
      :getPopupContainer="() => selectRef"
      @change="onSelectStructure"
    />
  </div>
</template>

<script setup lang="tsx">
import { computed, onMounted, ref, shallowRef } from 'vue';
import { fetchStationNetwork, fetchStructureTree } from '@/pages/screen/api';
import { TreeSelect } from 'ant-design-vue';
import { boundingExtent } from 'ol/extent';
import { fromLonLat } from 'ol/proj';
import { useRoute } from 'vue-router';
import { getMap, useOl } from '../../olMap/index.vue';

const selectRef = shallowRef();

defineOptions({
  inheritAttrs: false,
});

const route = useRoute();

const emit = defineEmits(['update:value']);
const { removeFeature, renderFeature } = useOl({
  onClick(res) {
    if (route.query.active) return;
    const { data, feature } = res;
    if (!data) return;
    const { lon, longitude, lat, latitude } = data;
    const lonLat = [lon || longitude, lat || latitude] as [number, number];
    removeFeature();
    renderStructureMarker();
    renderStationMarker();
    removeFeature([feature]);
    renderFeature({
      lonLat,
      data,
      style: {
        image: {
          src: data.stationCode
            ? '/static/screen/icon-station-active.png'
            : '/static/screen/icon-point-active.png',
          scale: 0.8,
        },
      },
    });
  },
});

const treeData = ref();
const treeId = ref<number>(undefined);

const allStructure = ref([]);
const currentStructure = ref([]);
const structure = computed(() => {
  return currentStructure.value?.length
    ? currentStructure.value
    : allStructure.value;
});

const stationList = ref([]);

const generateData = (tree) => {
  const structure = [];
  const formatTree = (tree) => {
    return tree.map((item) => {
      if (item.monitoringType === '2') {
        const { children = [], ...v } = item;
        structure.push(...children);
        return {
          ...v,
          structure: children,
        };
      } else if (item.children?.length) {
        item.children = formatTree(item.children);
      }
      return item;
    });
  };

  return {
    data: formatTree(tree),
    structure,
  };
};

const renderStructureMarker = () => {
  removeFeature();
  structure.value.forEach((item) => {
    renderFeature({
      lonLat: [item.lon, item.lat],
      data: item,
      style: {
        image: {
          src: '/static/screen/icon-point.png',
          scale: 0.8,
        },
      },
    });
  });
};

const renderStationMarker = () => {
  stationList.value.forEach((item) => {
    renderFeature({
      lonLat: [+item.longitude, +item.latitude],
      data: item,
      style: {
        image: {
          src: '/static/screen/icon-station.png',
          scale: 0.8,
        },
      },
    });
  });
};

const setView = () => {
  const transformedCoords = structure.value.map((item) => {
    return fromLonLat([item.lon, item.lat]);
  });
  const extent = boundingExtent(transformedCoords);
  getMap()
    .getView()
    .fit(extent, {
      padding: [200, 400, 200, 400],
      duration: 300,
    });
};

const findTree = (key, tree) => {
  const result = {};
  const stack = [...tree];
  while (stack.length > 0) {
    const node = stack.pop();
    if (node.children?.length) {
      stack.unshift(...node.children);
    }
    if (node.id === key) {
      Object.assign(result, node);
      break;
    }
  }
  return result;
};

const onSelectStructure = (value) => {
  const result: any = findTree(value, treeData.value);
  const { children, structure = [] } = result;
  if (children?.length) {
    children.forEach((item) => structure.push(...item.structure));
  }
  currentStructure.value = structure;
  renderStructureMarker();
  renderStationMarker();
  setView();
  // 大屏联动
  treeId.value = value;
  const params = {
    [result.pid ? 'regionId' : 'netId']: value,
  };
  emit('update:value', params);
};

onMounted(async () => {
  await fetchStationNetwork().then((res) => {
    stationList.value = res.rows;
  });
  fetchStructureTree().then((res) => {
    const { data, structure } = generateData(res.data);
    treeData.value = data;
    allStructure.value = structure;
    onSelectStructure(treeData.value?.[0]?.id);

    setView();
  });
});
</script>
